#ifndef __PKT_BUF_H__
#define __PKT_BUF_H__

#include <stdint.h>
#include <libcc_stl/list.h>


#define PKT_BODYLEN 2048

struct pkt
{
    struct
    {
        struct list_head list;

        uint8_t* head, *tail;
        uint8_t* data, *data_end;
        int data_len;

        uint8_t* mac_header;
        uint8_t* network_header;
        uint8_t* transport_header;
    } hdr;

    uint8_t body[PKT_BODYLEN];
} PACK;

#define PKT_LEN sizeof(struct pkt)

void pkt_init(struct pkt* p);

uint8_t* pkt_put(struct pkt* p, unsigned int len);

void pkt_append_data(struct pkt* p, uint8_t* from, unsigned int copy);
void pkt_append_u8(struct pkt* p, uint8_t from);
void pkt_append_u16(struct pkt* p, uint16_t from);
void pkt_append_u32(struct pkt* p, uint32_t from);

void pkt_prepend_data(struct pkt* p, uint8_t* from, unsigned int copy);
void pkt_prepend_u8(struct pkt* p, uint8_t from);
void pkt_prepend_u16(struct pkt* p, uint16_t from);
void pkt_prepend_u32(struct pkt* p, uint32_t from);

uint8_t* pkt_pick_data(struct pkt* p, unsigned int len);
uint8_t* pkt_pick_u8(struct pkt* p, uint8_t* to);
uint16_t* pkt_pick_u16(struct pkt* p, uint16_t* to);
uint32_t* pkt_pick_u32(struct pkt* p, uint32_t* to);

void pkt_reserve(struct pkt* p, int len);

unsigned int pkt_datalen(struct pkt* p);
uint8_t* pkt_mac_header(struct pkt* p);
uint8_t* pkt_network_header(struct pkt* p);
uint8_t* pkt_transport_header(struct pkt* p);

#endif

